using System;
using System.Web;
using System.Net;
using System.Collections;
using System.IO;
using System.Text;
using System.Security;

namespace Devsoft.Utilities
{
    public class Web
    {
        public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy
        {
            public TrustAllCertificatePolicy()
            { }

            public bool CheckValidationResult(ServicePoint sp,
                System.Security.Cryptography.X509Certificates.X509Certificate cert, WebRequest req, int problem)
            {
                return true;
            }
        }


        public enum TMethod
        {
            HTTP_POST, HTTP_GET
        };


        //protected CookieContainer _cookies = null;
        protected CookieCollection _Cookies = null;

        public string sourcehtml = string.Empty;

        public string ResponseUrl
        {
            get
            {
                return _ResponseUrl;
            }
            set
            {
                _ResponseUrl = value;
            }
        }

        protected string _ResponseUrl;

        public Web()
        {
            //
            // TODO: Add constructor logic here
            //
            //_cookies = new CookieContainer();
            System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
        }
        private string Encode(string oldValue)
        {
            //string newValue = oldValue.Replace("\"", "'");
            string newValue = oldValue;
            newValue = System.Web.HttpUtility.UrlEncode(newValue);
            newValue = newValue.Replace("%2f", "/");
            return newValue;
        }



        public string Query(String sUrl, Hashtable oForm, TMethod oMethod)
        {
            // Step 1a: Modify the POST string.
            string formPostData = "";
            if (oForm != null)
            {
                foreach (String postKey in oForm.Keys)
                {
                    string postValue = Encode((string)oForm[postKey]);
                    formPostData += string.Format("&{0}={1}", postKey, postValue);
                }
            }//End If
           
            if (formPostData != String.Empty)
            {
                formPostData = formPostData.Substring(1);
            }//End If


            // Create a request using a URL that can receive a post. 
            HttpWebRequest request = null;

            Stream dataStream = null;

            if (oMethod == TMethod.HTTP_POST)
            {

                request = (HttpWebRequest)WebRequest.Create(sUrl);
                //request.ProtocolVersion = HttpVersion.Version10;
                //request.AllowAutoRedirect = true;

                //request.
                // Set the Method property of the request to POST.

                request.CookieContainer = new CookieContainer();

                if (this._Cookies != null && this._Cookies.Count > 0)
                    request.CookieContainer.Add(_Cookies);

                request.Method = "POST";

                //formPostData = formPostData + "\r\n";
                byte[] byteArray;
                if (sUrl.IndexOf("result.jsp") > -1)
                {
                    request.Referer = "http://www.mobifone.com.vn/vietnamese/sms/textSms.jsp";
                    formPostData = "smsTplId=&mSelect=&pbList=&CCode=84&phonenum=84909272930&message=hello+motorola%0D%0Asafsf%0D%0AasfsF%0D%0A%0D%0A%28Dung+MobiFone+de+trung+xe+Ford%29&advFlg=ON&chargeFlg=1";
                }
                request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)";
                byteArray = Encoding.UTF8.GetBytes(formPostData);
                // Set the ContentType property of the WebRequest.
                request.ContentType = "application/x-www-form-urlencoded";
                // Set the ContentLength property of the WebRequest.
                request.ContentLength = byteArray.Length;



                // Get the request stream.
                dataStream = request.GetRequestStream();
                // Write the data to the request stream.
                dataStream.Write(byteArray, 0, byteArray.Length);
                // Close the Stream object.
                dataStream.Close();
                // Get the response.


            }//End If
            else
            {
                if (formPostData != string.Empty)
                {
                    request = (HttpWebRequest)WebRequest.Create(sUrl + "?" + formPostData);
                } //End If
                else
                {
                    request = (HttpWebRequest)WebRequest.Create(sUrl);
                }//End Else .. If

                

                request.CookieContainer = new CookieContainer();

                if (this._Cookies != null && this._Cookies.Count > 0)
                request.CookieContainer.Add(_Cookies);

                // Set the Method property of the request to GET.
                request.Method = "GET";
                request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)";

            }






            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            _Cookies = response.Cookies;
            // Display the status.
            Console.WriteLine(((HttpWebResponse)response).StatusDescription);
            // Get the stream containing content returned by the server.
            dataStream = response.GetResponseStream();
            // Open the stream using a StreamReader for easy access.
            StreamReader reader = new StreamReader(dataStream);
            // Read the content.
            string responseFromServer = reader.ReadToEnd();
            // Clean up the streams.

            sourcehtml = responseFromServer;
            _ResponseUrl = response.ResponseUri.OriginalString;
            reader.Close();
            dataStream.Close();
            response.Close();
            return responseFromServer;
        }

        public void Download(string strURL, string strFilename)
        {
            WebClient Client = new WebClient();            
            Client.DownloadFile(strURL, strFilename);

        }

        static public int GerErrorCode(Exception e)
        {
            if (e is WebException)
            {
                WebException webExcp = e as WebException;
                WebExceptionStatus status = webExcp.Status;
                // If status is WebExceptionStatus.ProtocolError, 
                //   there has been a protocol error and a WebResponse 
                //   should exist. Display the protocol error.
                if (status == WebExceptionStatus.ProtocolError)
                {                    
                    // Get HttpWebResponse so that you can check the HTTP status code.
                    HttpWebResponse httpResponse = (HttpWebResponse)webExcp.Response;
                    return (int)httpResponse.StatusCode;
                }
            }//End If
            return -1;
        }

        public string DownloadAsBase64(string strUrl)
        {
            WebClient Client = new WebClient();
            Client.Credentials = CredentialCache.DefaultCredentials;
            byte[] data = Client.DownloadData(strUrl);
            return Convert.ToBase64String(data);            
        }

        static public bool Is404Error(Exception e)
        {            
            return GerErrorCode (e) == 404;
        }
        static public bool Is503Error(Exception e)
        {
            return GerErrorCode(e) == 503;
        }
        static public string GetWebpageAsString(String sUrl, Hashtable oForm, TMethod oMethod, int nTry, Web web)
        {
            Web w = new Web();
            w._Cookies = web._Cookies;
            return ReadWebpage(sUrl, oForm, oMethod, nTry, w);
        }
        static public string GetWebpageAsString(String sUrl, Hashtable oForm, TMethod oMethod,int nTry)
        {
            Web w = new Web();
            return ReadWebpage(sUrl, oForm, oMethod, nTry, w);
            
        }

        private static string ReadWebpage(String sUrl, Hashtable oForm, TMethod oMethod, int nTry, Web w)
        {
            if (nTry == -1)
            {
                while (true)
                {
                    try
                    {
                        w.Query(sUrl, oForm, oMethod);
                        break;

                    }
                    catch (System.Exception e)
                    {
                        int k = GerErrorCode(e);
                        if (k == 404 || k == 403)
                        {
                            return string.Empty;
                        }//End If
                        System.Threading.Thread.Sleep(5000);
                    }
                }//End While
            }//End If
            else
            {
                int nCount = 0;
                while (nCount < nTry)
                {
                    try
                    {
                        w.Query(sUrl, oForm, oMethod);
                        break;
                    }
                    catch (System.Exception e)
                    {
                        int k = GerErrorCode(e);
                        if (k == 404 || k == 403)
                        {
                            return string.Empty;
                        }//End If
                        System.Threading.Thread.Sleep(5000);
                        nCount++;
                    }
                }//End While
            }//End Else

            return w.sourcehtml;
        }
    }
}
